home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-01-28 | 8.0 KB | 478 lines | [TEXT/MPS ] |
-
- /*
- File: ListOfLongs.cp
-
- Contains: TListOfLongs implementation.
-
- Developed by:
-
- Paul G Smith (commstalk hq & Full Moon Software, Inc)
-
- you can leave messages at (UK): 0727 844232; (US): 408 253 7199
- BUT I prefer to be contacted by e-mail
- AppleLink: SMITH.PG
- Internet: SMITH.PG@applelink.apple.com
-
- "SimpliFace" Sample code to accompany develop article
- on techniques for embedding scripts in applications.
-
-
- Ordered and un-ordered lists of long integers
-
- */
-
- #include "ListOfLongs.h"
-
- #ifndef __LIMITS__
- #include <Limits.h>
- #endif
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- #ifndef __PACKAGES__
- #include <Packages.h>
- #endif
-
-
-
-
- const short kLListChunkUnit = 16;
- const short kLListChunkSize = kLListChunkUnit*sizeof(long); // allocation chunk size
-
- /*******************************************************************************
- ** TListOfLongs: Constructor/Destructor
- ********************************************************************************/
-
- TListOfLongs::TListOfLongs()
- {
- fNumItems = 0;
- fDataHandle = NewHandle(kLListChunkSize);
- }
-
-
- TListOfLongs::TListOfLongs(const TListOfLongs& oldObj)
- {
- Handle h = oldObj.fDataHandle;
- HandToHand(&h);
- if (h)
- fDataHandle = h;
- fNumItems = oldObj.fNumItems;
- }
-
-
- TListOfLongs::~TListOfLongs(void)
- {
- if (fDataHandle)
- DisposHandle(fDataHandle);
- }
-
-
- TListOfLongs& TListOfLongs::operator=(const TListOfLongs& oldObj)
- {
- if (this != &oldObj)
- {
- Handle h = oldObj.fDataHandle;
- HandToHand(&h);
- if (h)
- {
- if (fDataHandle)
- DisposHandle(fDataHandle);
- fDataHandle = h;
- }
- fNumItems = oldObj.fNumItems;
- }
- return *this;
- }
-
-
- // the business
-
- Handle TListOfLongs::GetData(void)
- {
- Handle h = NULL;
- long numElems = fNumItems;
- OSErr err = 0;
-
- if ((numElems > 0) && fDataHandle)
- {
- HLock(fDataHandle);
- err = PtrToHand(*fDataHandle, &h, numElems*sizeof(long));
- HUnlock(fDataHandle);
- }
- else
- h = NewHandle(0);
-
- return h;
- }
-
-
- void TListOfLongs::SetData(Handle h)
- {
- fNumItems = 0;
-
- if (h)
- {
- long hs = GetHandleSize(h);
- long numItems = hs / sizeof(long);
- if (numItems < 0)
- numItems = 0;
- if (numItems)
- {
- Handle nh = h;
- OSErr err = HandToHand(&nh);
- if (!err)
- {
- fNumItems = numItems;
- DisposHandle(fDataHandle);
- fDataHandle = nh;
- }
- }
- }
- }
-
-
-
- OSErr TListOfLongs::ExpandDataHandle(long numLongs)
- {
- OSErr err = 0;
-
- if (fDataHandle)
- {
- long numElems = fNumItems;
- Handle h = fDataHandle;
- long oldSize = GetHandleSize(h);
-
- if (((numElems+numLongs) * sizeof(long)) > oldSize)
- {
- long addSize = (numLongs / kLListChunkUnit) + 1;
-
- SetHandleSize(h, oldSize + addSize * kLListChunkSize);
- err = MemError();
- }
- }
- else
- err = nilHandleErr;
-
- return err;
- }
-
-
-
- OSErr TListOfLongs::ShrinkDataHandle(long numLongs)
- {
- return noErr; // do nothing, for time being
- }
-
-
-
- OSErr TListOfLongs::InsertElement(long val)
- {
- OSErr err = noErr;
-
- if (!FindElement(val)) // if it's already there, do nothing
- {
- long lastItem = fNumItems;
- long** dh = (long**) fDataHandle;
-
- err = ExpandDataHandle(1); // grows dh, if more room is needed
-
- HLock(fDataHandle); // locks dh
-
- while (lastItem > 0)
- {
- long lastVal = (*dh)[lastItem-1]; // because array is indexed from 0
- if (lastVal > val)
- {
- (*dh)[lastItem] = lastVal;
- lastItem--;
- }
- else
- break; // insert here!
- }
- (*dh)[lastItem] = val;
- fNumItems = fNumItems + 1;
-
- HUnlock(fDataHandle);
- }
-
- return err;
- }
-
-
- void TListOfLongs::DeleteElement(long val)
- {
- long foundIndex = FindElement(val);
-
- if (foundIndex)
- {
- long numElems = fNumItems;
-
- if ((numElems > 0) && fDataHandle)
- {
- long** dh = (long**) fDataHandle;
- long currentIndex = foundIndex-1;
-
- HLock(fDataHandle); // locks dh
-
- while (currentIndex < numElems-1)
- {
- (*dh)[currentIndex] = (*dh)[currentIndex+1];
- currentIndex++;
- }
- fNumItems = fNumItems - 1;
-
- HUnlock(fDataHandle);
-
- ShrinkDataHandle(1);
- }
- }
- }
-
-
-
-
- long TListOfLongs::GetElement(long index)
- {
- long numElems = fNumItems;
-
- if ((numElems > 0) && fDataHandle)
- {
- long** dh = (long**) fDataHandle;
- long val = 0;
-
- HLock(fDataHandle); // locks dh
- val = (*dh)[index-1];
- HUnlock(fDataHandle);
-
- return val;
- }
- else
- return 0;
- }
-
-
- long TListOfLongs::FindElement(long val)
- {
- long numElems = fNumItems;
-
- if ((numElems > 0) && fDataHandle)
- {
- long** dh = (long**) fDataHandle;
- long currentIndex = 0;
- long currentVal = 0;
- long lowBound = 1;
- long highBound = numElems;
- Boolean found = false;
-
- HLock(fDataHandle); // locks dh
-
- do
- {
- currentIndex = (lowBound + highBound) >> 1; // == divide by 2
- currentVal = (*dh)[currentIndex-1];
- if (val < currentVal)
- highBound = currentIndex-1;
- else
- lowBound = currentIndex+1;
- found = (val == currentVal);
- } while (!(found || (lowBound > highBound)));
-
- if (!found)
- currentIndex = 0;
-
- HUnlock(fDataHandle);
-
- return currentIndex;
- }
- else
- return 0;
- }
-
-
-
- /*******************************************************************************
- ** TOrderedListOfLongs: Constructor/Destructor
- ********************************************************************************/
-
- TOrderedListOfLongs::TOrderedListOfLongs()
- {
- }
-
-
- TOrderedListOfLongs::TOrderedListOfLongs(const TOrderedListOfLongs& oldObj)
- {
- (TListOfLongs&)(*this) = (TListOfLongs&)oldObj;
- }
-
-
- TOrderedListOfLongs::~TOrderedListOfLongs(void)
- {
- }
-
-
- TOrderedListOfLongs& TOrderedListOfLongs::operator=(const TOrderedListOfLongs& oldObj)
- {
- (TListOfLongs&)(*this) = (TListOfLongs&)oldObj;
- return *this;
- }
-
-
- // the business
-
-
- OSErr TOrderedListOfLongs::InsertElement(long val)
- {
- return -1;
- }
-
-
- OSErr TOrderedListOfLongs::InsertElementAt(long val, long index)
- {
- OSErr err = noErr;
-
- if (!FindElement(val)) // if it's already there, do nothing
- {
- long lastItem = fNumItems;
- long** dh = (long**) fDataHandle;
-
- err = ExpandDataHandle(1); // grows dh, if more room is needed
-
- HLock(fDataHandle); // locks dh
-
- if (index <= 1)
- index = 1;
- while (lastItem >= index)
- {
- (*dh)[lastItem] = (*dh)[lastItem-1]; // because array is indexed from 0
- lastItem--;
- }
- (*dh)[lastItem] = val;
- fNumItems = fNumItems + 1;
-
- HUnlock(fDataHandle);
- }
-
- return err;
- }
-
-
- long TOrderedListOfLongs::FindElement(long val)
- {
- long numElems = fNumItems;
-
- if ((numElems > 0) && fDataHandle)
- {
- long** dh = (long**) fDataHandle;
- long currentIndex = numElems;
- long currentVal;
- Boolean found = false;
-
- HLock(fDataHandle); // locks dh
-
- do
- {
- currentVal = (*dh)[currentIndex-1];
- found = (val == currentVal);
- if (!found)
- currentIndex--;
- } while (!found && currentIndex > 0);
-
- if (!found)
- currentIndex = 0;
-
- HUnlock(fDataHandle);
-
- return currentIndex;
- }
- else
- return 0;
- }
-
-
-
- /*******************************************************************************
- ** TStackOfLongs: Constructor/Destructor
- ********************************************************************************/
-
- TStackOfLongs::TStackOfLongs()
- {
- }
-
-
- TStackOfLongs::TStackOfLongs(const TStackOfLongs& oldObj)
- {
- (TListOfLongs&)(*this) = (TListOfLongs&)oldObj;
- }
-
-
- TStackOfLongs::~TStackOfLongs(void)
- {
- }
-
-
- TStackOfLongs& TStackOfLongs::operator=(const TStackOfLongs& oldObj)
- {
- (TListOfLongs&)(*this) = (TListOfLongs&)oldObj;
- return *this;
- }
-
-
- // the business
-
-
- OSErr TStackOfLongs::InsertElement(long val)
- {
- return -1;
- }
-
-
- long TStackOfLongs::FindElement(long val)
- {
- return -1;
- }
-
-
-
- OSErr TStackOfLongs::PushElement(long val)
- {
- OSErr err = noErr;
- long lastItem = fNumItems;
- long** dh = (long**) fDataHandle;
-
- err = ExpandDataHandle(1); // grows dh, if more room is needed
-
- HLock(fDataHandle); // locks dh
- (*dh)[lastItem] = val;
- fNumItems = fNumItems + 1;
- HUnlock(fDataHandle);
-
- return err;
- }
-
-
- OSErr TStackOfLongs::PopElement(long *val)
- {
- OSErr err = noErr;
- long lastItem = fNumItems;
- long** dh = (long**) fDataHandle;
-
- HLock(fDataHandle); // locks dh
- if (lastItem > 0)
- *val = (*dh)[lastItem-1];
- else
- err = -1;
- fNumItems = fNumItems - 1;
- HUnlock(fDataHandle);
-
- if (!err)
- err = ShrinkDataHandle(1);
-
- return err;
- }
-